<script setup lang="ts">
import { ref, watch, nextTick, onMounted } from 'vue'
import {
  NInput,
  NButton,
  NIcon,
  NAvatar,
  type UploadCustomRequestOptions,
  NUpload,
  type UploadFileInfo,
  NPopover
} from 'naive-ui'
import { EllipsisHorizontal, Image } from '@vicons/ionicons5'
import type { UserVO } from '@/types/vo/UserVO'
import type { MessageVO } from '@/types/vo/MessageVO'
import { getMessageList } from '@/apis/front/chat'
import dayjs from 'dayjs'
import useWebSocket from '@/hooks/useWebSocket'
import type { MessageDTO } from '@/types/dto/MessageDTO'
import {upload} from "@/apis/common";
import {Icon} from "@iconify/vue";
import EmojiPicker from "@/views/Planet/components/EmojiPicker.vue";

const { currentContact } = defineProps<{
  currentContact: UserVO | undefined
}>()

const messages = ref<MessageVO[]>([])
const loading = ref(false)
const messagesContainerRef = ref<HTMLElement | null>(null) // Add ref for the messages container

const up = ref<InstanceType<typeof NUpload>>()


// Function to scroll to bottom of messages
const scrollToBottom = () => {
  nextTick(() => {
    if (messagesContainerRef.value) {
      messagesContainerRef.value.scrollTop =
        messagesContainerRef.value.scrollHeight
    }
  })
}

const getMessages = async () => {
  try {
    loading.value = true
    const res = await getMessageList(currentContact?.userName || '')
    messages.value = res.data.data

    scrollToBottom()
  } finally {
    loading.value = false
  }
}

defineEmits<{
  (e: 'send-message', content: string): void
}>()

const userStore = useUserStore()
const message = useMessage()

const form = ref<MessageDTO>({
  type: 'send',
  fromId: userStore.userInfo?.userName,
  toId: currentContact?.userName,
  content: '',
})

watch(
  () => messages.value,
  () => {
    scrollToBottom()
  },
  { deep: true },
)

watch(
  () => currentContact,
  () => {
    form.value.toId = currentContact?.userName
    form.value.fromId = userStore.userInfo?.userName
    form.value.content = ''
    form.value.picUrls = []
    up.value?.clear()
    if (currentContact?.id) {
      getMessages()
    }
  },
  {
    deep: true,
    immediate: true,
  },
)

onMounted(() => {
  scrollToBottom()
})



const { sendMessage, isConnected } = useWebSocket(
  'ws://localhost:3000/ws/' + userStore.userInfo?.userName,
  message => {
    messages.value.push(message)
    // 消息确认
    sendMessage({
      ...message,
      type: 'receive',
    })
    scrollToBottom()
  },
)

// 上传图片
const customRequest = async ({ file, onFinish }: UploadCustomRequestOptions) => {
  const formData = new FormData()
  // 上传图片, 取出file的最后一个文件
  console.log(file.file)
  formData.append('file', file.file as File)
  const res = await upload(formData)
  form.value.picUrls?.push(res.data.data)
  onFinish()
}

const onRemove = ({index}:{ file: UploadFileInfo, fileList: Array<UploadFileInfo>, index: number }) => {
  // 删除图片
  form.value.picUrls?.splice(index, 1)
}

const handleSelectEmoji = (emoji: string) => {
  form.value.content += emoji
}



const sendMessageWithObject = async () => {
  if(!form.value.content && !form.value.picUrls?.length){
    message.error('请输入内容')
    return
  }
  form.value.fromId = userStore.userInfo?.userName
  form.value.toId = currentContact?.userName
  if(!form.value.toId){
    message.error('请选择用户')
    return
  }
  if (isConnected) {
    sendMessage(form.value)
    messages.value.push({
      fromId: userStore.userInfo?.userName,
      toId: currentContact?.userName,
      content: form.value.content,
      picUrls: form.value.picUrls,
      createdTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
    })
    form.value.content = ''
    form.value.picUrls = []
    up.value?.clear()
  } else {
    message.error('请先建立连接')
  }
}
</script>

<template>
  <div class="chat-area">
    <div class="chat-header">
      <div class="contact-name">{{ currentContact?.nickName }}</div>
      <div class="more-options">
        <n-button text>
          <template #icon>
            <n-icon><EllipsisHorizontal /></n-icon>
          </template>
        </n-button>
      </div>
    </div>

    <div ref="messagesContainerRef" class="messages-container">

      <div
        v-for="message in messages"
        :key="message.id"
        class="message"
        :class="{
          'message-sent': message.fromId === userStore.userInfo?.userName,
          'message-received': message.fromId !== userStore.userInfo?.userName,
        }"
      >
        <div class="message-time">
          {{ dayjs(message.createdTime).format('YYYY-MM-DD HH:mm') }}
        </div>
        <!--      自己的-->
        <div
          class="message-avatar flex items-start justify-end gap-5px"
          v-if="message.fromId === userStore.userInfo?.userName"
        >
          <div class="message-content">
            <span>{{ message.content }}</span>
            <div class="flex gap-5px">
              <n-image
                v-for="picUrl in message.picUrls"
                :key="picUrl"
                :src="picUrl"
                :preview-src-list="message.picUrls"
                width="100"
                height="100"
              />
            </div>
          </div>
          <n-avatar
            :src="
              userStore.userInfo?.avatar ||
              'https://07akioni.oss-cn-beijing.aliyuncs.com/demo1.JPG'
            "
          />
        </div>
        <!--      对方的-->
        <div class="message-avatar flex justify-start gap-5px items-start" v-else>
          <n-avatar
            :src="
              currentContact?.avatar ||
              'https://07akioni.oss-cn-beijing.aliyuncs.com/demo1.JPG'
            "
          />
          <div class="message-content">
            <span>{{ message.content }}</span>
            <div class="flex gap-5px">
              <n-image
                v-for="picUrl in message.picUrls"
                :key="picUrl"
                :src="picUrl"
                :preview-src-list="message.picUrls"
                width="100"
                height="100"
              />
            </div>
          </div>
        </div>

      </div>
    </div>

    <div class="message-input-container">
      <n-upload abstract :list-type="'image'" :custom-request="customRequest" @remove="onRemove" ref="up">
        <div class="message-tools gap-5px">
          <n-popover
            trigger="click"
            placement="top"
            :show-arrow="false"
            style="padding: 0"
          >
            <template #trigger>
              <n-button text size="small">
                <template #icon>
                  <Icon icon="iconoir:emoji" width="24" height="24" />
                </template>
              </n-button>
            </template>
            <EmojiPicker @select="handleSelectEmoji" />
          </n-popover>
          <n-upload-trigger #="{ handleClick }" abstract>
            <n-button text @click="handleClick">
              <template #icon>
                <n-icon><Image /></n-icon>
              </template>
            </n-button>
          </n-upload-trigger>
        </div>
        <n-upload-file-list></n-upload-file-list>
        <n-input
          v-model:value="form.content"
          type="textarea"
          :autosize="{ minRows: 3 }"
          placeholder="输入消息..."
          class="message-input"
          @keydown.shift.enter.prevent="sendMessageWithObject"
        />
        <div class="send-hint">按 Shift + Enter 发送消息</div>
      </n-upload>
    </div>
  </div>
</template>

<style scoped>
.chat-area {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  background-color: #fff;
}

.chat-header {
  padding: 16px;
  border-bottom: 1px solid #e0e0e0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.contact-name {
  font-size: 18px;
  font-weight: 500;
}

.messages-container {
  flex-grow: 1;
  padding: 16px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.notification-message {
  background-color: #f5f5f5;
  padding: 8px 12px;
  border-radius: 4px;
  color: #666;
  text-align: center;
  margin: 8px 0;
  font-size: 14px;
}


.message {
  max-width: 70%;
  margin-bottom: 16px;
  width: auto;
  display: flex;
  flex-direction: column;
}

.message-sent {
  align-self: flex-end;
  .message-time {
    font-size: 12px;
    color: #999;
    margin-top: 4px;
    align-self: flex-end;
  }
}

.message-received {
  align-self: flex-start;
  .message-time {
    font-size: 12px;
    color: #999;
    margin-top: 4px;
    align-self: flex-start;
  }
}

.message-content {
  background-color: #ecf5ff;
  padding: 10px 14px;
  border-radius: 8px;
  word-break: break-word;
}

.message-sent .message-content {
  background-color: #95d5ff;
  color: #000;
}



.message-input-container {
  padding: 12px 16px;
  border-top: 1px solid #e0e0e0;
  position: relative;
}

.message-tools {
  display: flex;
  margin-bottom: 8px;
}

.message-input {
  width: 100%;
  border-radius: 4px;
}

.send-hint {
  position: absolute;
  right: 24px;
  bottom: 20px;
  font-size: 12px;
  color: #999;
}
</style>
